﻿using System;
using System.Collections.Generic;

namespace GameBasic.IO
{
    /// <summary>
    /// Execute single file task
    /// </summary>
    public class FileTask : PoolingTask
    {
        public FileOperation operation;

        public FileTask() { }

        public FileTask(in FileOperation op)
        {
            this.operation = op;
        }

        protected override void ExecuteImpl()
        {
            operation.Execute();
        }
    }

    /// <summary>
    /// Execute a list of <see cref="FileOperation"/>
    /// </summary>
    public class FileTasks : PoolingTask
    {
        public List<FileOperation> operations;
        public bool clearOnComplete;
        public Action<FileTasks, TaskEvent> callback;
        int completeCount;

        public int Complete => completeCount;
        public int Total => operations.Count;

        public FileTasks(int count)
        {
            operations = new List<FileOperation>(count);
        }

        public FileTasks(params FileOperation[] operations)
        {
            this.operations = new List<FileOperation>(operations);
        }

        public FileTasks(FileOperation[] operations, Action<FileTasks, TaskEvent> callback)
        {
            this.operations = new List<FileOperation>(operations);
            this.callback = callback;
        }

        override protected void ExecuteImpl()
        {
            // init
            completeCount = 0;
            // start
            callback?.Invoke(this, TaskEvent.OnStart);

            // TODO: sort
            for (int i = 0, length = operations.Count; i < length; i++)
            {
                var task = operations[i];
                operations[i] = task.Execute();
                // UpdateProgress
                completeCount++;
                progress = (float)Complete / Total;
                callback?.Invoke(this, TaskEvent.OnUpdate);
            }

            // complete
            callback?.Invoke(this, TaskEvent.OnComplete);
            if (clearOnComplete)
                Clear();
        }

        public void Clear()
        {
            callback = null;
            completeCount = 0;
            operations.Clear();
        }

        public override string ToString()
        {
            string result = $"{Complete} / {Total}";
            for (int i = 0; i < operations.Count; i++)
                result += $"\n {operations[i].type}: {operations[i].path}";

            return result;
        }
    }
}